package com.easytouch.core.utils;

import com.easytouch.core.Configure;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

/**
 * 记录日志的工具类
 * 使用前需要设置maintainDays、isInfoEnable、isDebugEnable、isErrorEnable 这几个静态变量
 * Created by gulin on 2017/7/17.
 */

public class Log {

	private static final String DIRECTORY_LOG = "log";
	private static final String INFO = "INFO";
	private static final String DEBUG = "DEBUG";
	private static final String ERROR = "ERROR";

	public static int maintainDays = 5; //日志保留天数
	public static boolean isInfoEnable = true; //是否打印info
	public static boolean isDebugEnable = true; //是否打印debug
	public static boolean isErrorEnable = true; //是否打印error

	private String mFileName; //当前日志文件名

	public Log() {

		this("log.txt");

	}

	public Log(String fileName) {

		mFileName = fileName;
		createDirectoryAndDeleteOthers();
	}

	/**
	 * 创建今天的目录，检查并删除非maintainDays内的目录及下面的文件
	 */
	private void createDirectoryAndDeleteOthers() {
		if(Configure.path == null)
		{
			return;
		}
		//建立今天的目录
		String today = getDate(0);
		File logDir = new File(Configure.path + "/" + DIRECTORY_LOG);
		if (!logDir.exists()) {
			logDir.mkdirs();
		}
		File todayDir = new File(logDir.getAbsolutePath() + "/" + today);
		if (!todayDir.exists()) {
			todayDir.mkdirs();
		}
		//删除非maintainDays内的目录及下面的文件
		ArrayList<String> validDir = new ArrayList<String>(); //先把当前合法的目录保存起来
		validDir.add(today);
		for (int i = -1; i > -maintainDays; i--) {
			String dir = getDate(i);
			validDir.add(dir);
		}
		//获取到log目录下的所有文件和目录
		File[] currentFiles;
		currentFiles = logDir.listFiles();
		if (currentFiles == null)
			return;
		for (File file : currentFiles) {
			if (file.isDirectory()) {
				String name = file.getName();
				if (name.equals(".") || name.equals(".."))
					continue;
				boolean isFind = false;
				for (String f : validDir) {
					if (name.equals(f)) {
						isFind = true;
						break;
					}
				}
				if (!isFind) {
					deleteDir(file);
				}
			} else {
				file.delete();
			}
		}
	}

	/**
	 * 递归删除目录
	 *
	 * @param pFile 要删除的目录
	 */
	private void deleteDir(File pFile) {
		if (pFile.isDirectory()) {
			File[] currentFiles;
			currentFiles = pFile.listFiles();
			if (currentFiles == null) {
				pFile.delete();
				return;
			}
			for (File file : currentFiles) {
				if (file.isDirectory()) {
					String name = file.getName();
					if (name.equals(".") || name.equals(".."))
						continue;
					deleteDir(file);
				} else {
					file.delete();
				}
			}
		}
		pFile.delete();
	}

	public void i(final String log) {
		if(isInfoEnable) {
			log(log, INFO);
		}
	}

	public void d(final String log)
	{
		if(isDebugEnable) {
			log(log, DEBUG);
		}
	}

	public void e(final String log)
	{
		if(isErrorEnable) {
			log(log, ERROR);
		}
	}
	
	private void log(final String pLog, final String pLevel){
		if(Configure.path == null || Configure.version == null)
		{
			return;
		}
        createDirectoryAndDeleteOthers();
        String today = getDate(0);
        File logFile = new File(Configure.path + "/" + DIRECTORY_LOG + "/" + today + "/" + mFileName);
        FileOutputStream fos = null;
		BufferedOutputStream bw = null;
        try {
            if (!logFile.exists()) {
                logFile.createNewFile();
            }
            fos = new FileOutputStream(logFile, true);
            bw = new BufferedOutputStream(fos);
			SimpleDateFormat sd = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss:SSS", Locale.US);
			String time = sd.format(new Date());
            String l = time +", "+ Configure.version + " " + pLevel +": " + pLog + "\r\n";
            bw.write(l.getBytes());
            bw.flush();
        } catch (IOException e)
        {
            e.printStackTrace();
        } finally{
			try {
				if(bw != null)
					bw.close();
				if(fos != null)
					fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	
	/**
	 * 得到给定偏移日子的日期
	 * @param day 偏移，0表示今天，正数表示往后day天，负数表示往前day天
	 * @return 日期
	 */
	private String getDate(int day)
	{
		Calendar calendar = Calendar.getInstance();
		if(day != 0)
		{
			calendar.add(Calendar.DATE, day);
		}
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd", Locale.US);
    	return sdf.format(calendar.getTime());
	}

}
